{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "Digit Classification.ipynb",
      "private_outputs": true,
      "provenance": [],
      "collapsed_sections": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    }
  },
  "cells": [
    {
      "cell_type": "code",
      "metadata": {
        "id": "AJj2-4z3dBfk"
      },
      "source": [
        "#https://www.sitepoint.com/keras-digit-recognition-tutorial/"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "dNfZ_DkSSu2b"
      },
      "source": [
        "Importing Dataset"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "kHhJZ1f9He_U"
      },
      "source": [
        "import numpy as np\r\n",
        "\r\n",
        "def create_scaler(*args):\r\n",
        "  min_d = np.min(args[0])\r\n",
        "  max_d = np.max(args[0])\r\n",
        "  for partition in args:\r\n",
        "    if np.min(partition) < min_d:\r\n",
        "      min_d = np.min(partition)\r\n",
        "    if np.max(partition) > max_d:\r\n",
        "      max_d = np.max(partition)\r\n",
        "  return [min_d, max_d]\r\n",
        "\r\n",
        "def normalizer(scaler, df):\r\n",
        "  min_d = scaler[0]\r\n",
        "  max_d = scaler[1]\r\n",
        "  normalized_df = (df - min_d) / (max_d - min_d)\r\n",
        "  return normalized_df\r\n",
        "\r\n",
        "def denormalizer(scaler, normalized_df):\r\n",
        "  min_d = scaler[0]\r\n",
        "  max_d = scaler[1]\r\n",
        "  denormalized_df = normalized_df * (max_d - min_d) + min_d\r\n",
        "  return denormalized_df"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "_Yr7S-MLN65-"
      },
      "source": [
        "from keras.datasets import mnist\n",
        "import matplotlib.pyplot as plt\n",
        "%matplotlib inline"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Ec6C2zW6ODK_"
      },
      "source": [
        "(X_train, y_train), (X_test, y_test) = mnist.load_data()\n",
        "print(X_train.shape)\n",
        "print(X_test.shape)\n",
        "print(y_train.shape)\n",
        "print(y_test.shape)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xSWxihNlSs1o"
      },
      "source": [
        "Preprocessing"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "VdnVriRNOAu-"
      },
      "source": [
        "#show one image with label\n",
        "print(y_train[0])\n",
        "plt.imshow(X_train[0], cmap='Greys')\n",
        "plt.show()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "oxBNwNafOVqU"
      },
      "source": [
        "#change shape to IMAGES only for CNN input\n",
        "X_train = X_train.reshape(60000, 28, 28, 1)\n",
        "X_test = X_test.reshape(10000, 28, 28, 1)\n",
        "#the labels are already in an acceptable shape"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "4Hrqvb_KHdn3"
      },
      "source": [
        "#normalize image data only\r\n",
        "scaler = create_scaler([0, 255])\r\n",
        "X_train_ = normalizer(scaler, X_train)\r\n",
        "X_test_ = normalizer(scaler, X_test)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "sijhvyQqPUzU"
      },
      "source": [
        "#DEPRECATED: normalize, identical to the new method\n",
        "import numpy as np\n",
        "X_train = np.array(X_train, dtype=np.float64)\n",
        "X_test = np.array(X_test, dtype=np.float64)\n",
        "X_train /= 255\n",
        "X_test /= 255"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "B0LuUKaHOXNm"
      },
      "source": [
        "'''\n",
        "#se lo si attiva, il modello si sputtana\n",
        "from keras.utils import to_categorical\n",
        "num_classes = 10\n",
        "\n",
        "y_train = to_categorical(y_train, num_classes)\n",
        "y_test = to_categorical(y_test, num_classes)\n",
        "#y sono i labels one_hot: [0., 0., 0., 0., 0., 0., 0., 1., 0., 0.]\n",
        "'''"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ggpGXDo8Sx72"
      },
      "source": [
        "CNN"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "f65mT0M1QFhz"
      },
      "source": [
        "import tensorflow\n",
        "from keras.models import Sequential\n",
        "from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D\n",
        "\n",
        "model = Sequential()\n",
        "model.add(Conv2D(32, kernel_size=(3, 3),\n",
        "     activation='relu',\n",
        "     input_shape=(28, 28, 1))) #image size\n",
        "model.add(Conv2D(64, (3, 3), activation='relu'))\n",
        "model.add(MaxPooling2D(pool_size=(2, 2)))\n",
        "model.add(Dropout(0.25))\n",
        "model.add(Flatten())\n",
        "model.add(Dense(128, activation='relu'))\n",
        "model.add(Dropout(0.5))\n",
        "model.add(Dense(10, activation='softmax')) #number of classes\n",
        "\n",
        "model.compile(loss='sparse_categorical_crossentropy',\n",
        "      optimizer='adam',\n",
        "      metrics=['accuracy'])\n",
        "\n",
        "batch_size = 128\n",
        "epochs = 10\n",
        "\n",
        "model.fit(X_train_, y_train,\n",
        "          batch_size=batch_size,\n",
        "          epochs=epochs,\n",
        "          verbose=2,\n",
        "          validation_data=(X_test, y_test))\n",
        "\n",
        "score = model.evaluate(X_test, y_test, verbose=2)\n",
        "print('Test loss:', score[0])\n",
        "print('Test accuracy:', score[1])"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "4tqjFmu9TG31"
      },
      "source": [
        "#   summarize model_1\r\n",
        "#input layer not included\r\n",
        "model.summary(line_length=None, positions=None, print_fn=None)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "TE0olDrcTK3p"
      },
      "source": [
        "#   summarize model_2\r\n",
        "#input layer is included\r\n",
        "from keras.utils.vis_utils import plot_model\r\n",
        "plot_model(model, show_shapes=True, show_layer_names=True)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "oYLj934QAhDe"
      },
      "source": [
        "Image"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "AKbC8SlMdSxF"
      },
      "source": [
        "import imageio\n",
        "import numpy as np\n",
        "from matplotlib import pyplot as plt\n",
        "\n",
        "im = imageio.imread(\"https://i.imgur.com/a3Rql9C.png\")"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "wdCv4kFndULD"
      },
      "source": [
        "#visualize image\n",
        "gray = np.dot(im[...,:3], [0.299, 0.587, 0.114])\n",
        "plt.imshow(gray, cmap = plt.get_cmap('gray'))\n",
        "plt.show()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "_n21EU0odYGP"
      },
      "source": [
        "# reshape the image\n",
        "gray = gray.reshape(1, 28, 28, 1)\n",
        "\n",
        "# normalize image\n",
        "gray /= 255"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HJN_O6h6ATLC"
      },
      "source": [
        "Prediction"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "dUWdmHjMs0Yd"
      },
      "source": [
        "#predict digit in x_train\n",
        "prediction = model.predict(X_test[0].reshape(1, 28, 28, 1))\n",
        "print(y_test[0], prediction.argmax())"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "0ZbPf9GNQ3T8"
      },
      "source": [
        "print(y_test[0])\r\n",
        "plt.imshow(X_test[0], cmap='Greys')\r\n",
        "plt.show()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "V3DQftc5tU-C"
      },
      "source": [
        "#predict digit from img\n",
        "prediction = model.predict(gray)\n",
        "print(prediction.argmax())"
      ],
      "execution_count": null,
      "outputs": []
    }
  ]
}